/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ChartForm.java
 *
 * Created on 05.12.2008, 14:48:45
 */
package gui;

import core.CalculationException;
import core.PdmOptimization;
import facilitator.SolutionProvider;
import facilitator.Tool;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.sourceforge.chart2d.Chart2DProperties;
import net.sourceforge.chart2d.Dataset;
import net.sourceforge.chart2d.GraphChart2DProperties;
import net.sourceforge.chart2d.GraphProperties;
import net.sourceforge.chart2d.LBChart2D;
import net.sourceforge.chart2d.LegendProperties;
import net.sourceforge.chart2d.MultiColorsProperties;
import net.sourceforge.chart2d.Object2DProperties;
import util.Util;

/**
 *
 * @author Niki
 */
public class ChartForm extends javax.swing.JFrame implements ActionListener, AdjustmentListener {
    private JSeparator jSeparator2;

    private float getCustomGreatestValue(List<PdmOptimization> pdmOpts) {
        if(this.jCheckBox1.isSelected()){
            float max = 0;
            try {
                for (int x = 0; x < pdmOpts.size(); x++) {
                    double[] relOutputWeight = Tool.getRelWeights(pdmOpts.get(x).getOptimizationOutputWeights());
                    for (int i = 0; i < relOutputWeight.length; i++) {
                        if (relOutputWeight[i] > max) {
                            max = Float.parseFloat(String.valueOf(Util.truncate(relOutputWeight[i], 0)));
                        }
                    }
                }
            } catch (CalculationException ex) {
                Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
            }
            if(max % 10 == 0){
                max +=10;
            }
            max = Util.roundUp(max / 10, 0) * 10;
            return max;
        }
        else{
            return 60;
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel2 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        label1 = new java.awt.Label();
        jSeparator1 = new javax.swing.JSeparator();
        jCheckBox1 = new javax.swing.JCheckBox();
        jButton1 = new javax.swing.JButton();
        jPanel6 = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jProgressBar1 = new javax.swing.JProgressBar();
        jScrollBar1 = new javax.swing.JScrollBar();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("PDM Visualization");
        setBackground(java.awt.Color.gray);
        setForeground(java.awt.Color.gray);
        setResizable(false);

        jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 748, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 101, Short.MAX_VALUE)
        );

        jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.X_AXIS));

        jPanel4.setBackground(java.awt.Color.gray);
        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Desired Weight Profile (%)", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 11), new java.awt.Color(255, 255, 255))); // NOI18N
        jPanel4.setForeground(new java.awt.Color(255, 255, 255));

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 507, Short.MAX_VALUE)
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 21, Short.MAX_VALUE)
        );

        jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Status"));

        label1.setAlignment(java.awt.Label.CENTER);
        label1.setBackground(java.awt.Color.green);
        label1.setFont(new java.awt.Font("Dialog", 1, 10));
        label1.setText("Ready");

        jCheckBox1.setText("autoscale");
        jCheckBox1.setToolTipText("<html><b>Autoscale function.</b> If activated the chart is rescaled <br>with every movement to the highest element (zoom),<br> if deactivated the chart will always stay at inital high.</html>");

        jButton1.setText("revalidate");
        jButton1.setToolTipText("<html>Revalidates and calculates all product profiles <br>according to the defined <b>Desired Weight Profile</b>.</html>");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 211, Short.MAX_VALUE)
                    .addComponent(label1, javax.swing.GroupLayout.DEFAULT_SIZE, 211, Short.MAX_VALUE)
                    .addGroup(jPanel5Layout.createSequentialGroup()
                        .addComponent(jCheckBox1)
                        .addContainerGap(140, Short.MAX_VALUE))
                    .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 211, Short.MAX_VALUE)))
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addComponent(label1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(15, 15, 15)
                .addComponent(jButton1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jCheckBox1)
                .addContainerGap(122, Short.MAX_VALUE))
        );

        jPanel6.setBackground(java.awt.Color.gray);
        jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Sum of Weights", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 11), new java.awt.Color(255, 255, 255))); // NOI18N
        jPanel6.setLayout(new javax.swing.BoxLayout(jPanel6, javax.swing.BoxLayout.X_AXIS));

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Flexibility"));

        jProgressBar1.setFont(jProgressBar1.getFont().deriveFont(jProgressBar1.getFont().getStyle() | java.awt.Font.BOLD));
        jProgressBar1.setToolTipText("Show the amount of flexibility the selected products are given.");
        jProgressBar1.setStringPainted(true);

        jScrollBar1.setOrientation(javax.swing.JScrollBar.HORIZONTAL);
        jScrollBar1.setToolTipText("<html>Use this slider to set the amount of flexibility that <br>the selected products are given to optimize their weights.</html>");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jProgressBar1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
            .addComponent(jScrollBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(jScrollBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 519, Short.MAX_VALUE))
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, 212, Short.MAX_VALUE)
                    .addComponent(jPanel5, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
            .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jPanel5, jPanel6});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, 243, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(5, 5, 5)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jPanel4, jPanel6});

        layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jPanel3, jPanel5});

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        double sum = 0;
        for (int i = 0; i < this.urmSpinner.length; i++) {
            sum += Double.parseDouble(urmSpinner[i].getValue().toString());
        }

        if (sum != 100d) {
            JOptionPane.showMessageDialog(null, "Sum of weightings must sum up to 100%", "Warning", JOptionPane.OK_OPTION);
            return;

        }


        try {
            this.label1.setText("Calculating...");
            this.label1.setBackground(Color.ORANGE);
            this.calculate();
            this.label1.setText("Ready");
            this.label1.setBackground(Color.GREEN);
        } catch (CalculationException ex) {
            Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_jButton1ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JProgressBar jProgressBar1;
    private javax.swing.JScrollBar jScrollBar1;
    private javax.swing.JSeparator jSeparator1;
    private java.awt.Label label1;
    // End of variables declaration//GEN-END:variables
    private SolutionProvider provider;
    private JSpinner[] urmSpinner;
    private LBChart2D chart;
    private Label weightSum;
    private JButton equalise;
    private String[] categories = new String[] {"controlling","accounting",
    "logistics","purchasing","reporting","services","sales", "management"};

    /** Creates new form ChartForm */
    public ChartForm() {
        try {
            Util.setLookAndFeel();
            initComponents();

            initServiceLayer();

            initManualComponents();

            calculate();

            this.pack();
            this.setMinimumSize(this.getSize());
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            this.setLocation((screenSize.width - this.getSize().width) / 2,
                    (screenSize.height - this.getSize().height) / 2);
            this.setVisible(true);
        } catch (Exception ex) {
            Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
        new ChartForm().setVisible(true);
        }
        });*/
    }

    private void initManualComponents() {
        loadDmuTable();
        loadWeightingsPanel();
        setInitialDmuWeights();
        setAutoScale();

    }

    private void initServiceLayer() {
        try {
            //load new Solutionprovider containing all necessary dmulist etc
            this.provider = new SolutionProvider();
            this.provider.loadDemoData();
        } catch (CalculationException ex) {
            Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NumberFormatException ex) {
            Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
// End of variables declaration

    private void loadDmuTable() {
        jPanel2.setLayout(new BoxLayout(jPanel2, BoxLayout.Y_AXIS));
        this.jPanel2.add(DmuPanel.getHeaderRow());
        ((DmuPanel) this.jPanel2.getComponent(0)).jCheckBox1.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (((DmuPanel) jPanel2.getComponent(0)).isChecked()) {
                    for (Object o : jPanel2.getComponents()) {
                        if (!((DmuPanel) o).isHeader) {
                            ((DmuPanel) o).setChecked(true);
                        }

                    }
                } else {
                    ((DmuPanel) jPanel2.getComponent(1)).setChecked(true);
                    for (int i = 2; i < jPanel2.getComponentCount(); i++) {
                        ((DmuPanel) jPanel2.getComponent(i)).setChecked(false);
                    }

                }
                scrollBarChanged(jScrollBar1.getValue(), false);
                setDmuListColors();

            }
        });
        for (int i = 0; i <
                this.provider.dmuList.size(); i++) {
            DmuPanel newPanel = new DmuPanel(Tool.erpVendors.get(i), i);
            newPanel.jCheckBox1.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    ((DmuPanel) jPanel2.getComponent(0)).setChecked(false);
                    boolean checked = false;
                    for (int i = 0; i <
                            jPanel2.getComponentCount(); i++) {
                        DmuPanel temp = (DmuPanel) jPanel2.getComponent(i);
                        if (!temp.isHeader) {
                            if (temp.isChecked()) {
                                checked = true;
                            }
                        }
                    }
                    if (!checked) {
                        JOptionPane.showMessageDialog(null, "Please select at least 1 product", "Warning", JOptionPane.OK_OPTION);
                        ((DmuPanel) jPanel2.getComponent(1)).setChecked(true);
                    }

                    scrollBarChanged(jScrollBar1.getValue(), false);
                    setDmuListColors();

                }
            });
            this.jPanel2.add(newPanel);
        }

        ((DmuPanel) jPanel2.getComponent(1)).setChecked(true);
    }

    private void loadWeightingsPanel() {
        jPanel4.setLayout(new BoxLayout(jPanel4, BoxLayout.X_AXIS));
        jSeparator2 = new javax.swing.JSeparator();
        jSeparator2.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        //jSeparator2.setIgnoreRepaint(true);
        jSeparator2.setMinimumSize(new Dimension(200, 2));
        //jSeparator2.setMaximumSize(new Dimension(210, 20));
        jSeparator2.setBackground(java.awt.Color.gray);
        jSeparator2.setForeground(java.awt.Color.gray);
        jPanel4.add(jSeparator2);
        
        urmSpinner =
                new JSpinner[provider.getRelUrmWeights().length];
        for (int i = 0; i < this.provider.getRelUrmWeights().length; i++) {
            JSpinner spin = new JSpinner();
            SpinnerModel model = new SpinnerNumberModel(1, 1, 100, 0.5);
            model.addChangeListener(new ChangeListener() {

                public void stateChanged(ChangeEvent e) {
                    urmWeightChanged();
                }
            });
            spin.setModel(model);
            spin.setToolTipText("<html>Set weight for <b>" + categories[i] + "</b<</html>");
            urmSpinner[i] = spin;
            jPanel4.add(spin);
        }

        weightSum = new Label(" = 100%");
        weightSum.setPreferredSize(urmSpinner[0].getSize());
        jPanel6.add(weightSum);
        equalise =
                new JButton("equalise");
        equalise.setForeground(Color.BLACK);
        equalise.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                for (JSpinner spin : urmSpinner) {
                    spin.setValue(12.5);
                }
            }
        });
        equalise.setToolTipText("<html>Resets the weightings for all categories to equal.<br>  use this function if you have <b>no information on your <br>needs or preferences</b>.</html>");
        jPanel6.add(equalise);

        jPanel6.revalidate();
        jPanel6.repaint();
        jPanel4.revalidate();
        jPanel4.repaint();
    }

    private void setAutoScale() {
        this.jCheckBox1.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                try {
                    updateChartData(provider.getPdmOptimizations(getSelectedDmus(), getReverseValue(jScrollBar1.getValue())));
                } catch (CalculationException ex) {
                    Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
    private void setInitialDmuWeights() {
        for (int i = 0; i < this.urmSpinner.length; i++) {
            urmSpinner[i].setValue(Util.roundHalfUp(this.provider.getRelUrmWeights()[i], 0));
        }

    }

    private void urmWeightChanged() {
        //set summe and chart
        double sum = 0;
        for (int i = 0; i < this.urmSpinner.length; i++) {
            sum += Double.parseDouble(urmSpinner[i].getValue().toString());
        }

        this.weightSum.setText(" = " + sum + "%");
        if (sum != 100) {
            this.weightSum.setBackground(Color.RED);
            this.weightSum.setForeground(Color.WHITE);
        } else {
            this.weightSum.setBackground(Color.GREEN);
            this.weightSum.setForeground(Color.BLACK);
        }

        if (this.chart != null) {
            updateChartData(this.getChartUrmValues());
        }

        if (this.isIdentitical(provider.getRelUrmWeights(), this.getChartUrmValues())) {
            this.label1.setBackground(Color.GREEN);
            this.label1.setText("Ready");
        } else {
            this.label1.setBackground(Color.RED);
            this.label1.setText("Please revalidate");
        }

    }

    private boolean isIdentitical(double[] urmVal, double[] urmNew) {
        for (int i = 0; i <
                urmVal.length; i++) {
            if (Util.roundHalfUp(urmVal[i], 0) != urmNew[i]) {
                //Util.print(Util.roundHalfDown(urmVal[i], 0) + " -- " + urmNew[i]);
                return false;
            }

        }
        return true;
    }

    private double[] getChartUrmValues() {
        double[] urmValues = new double[urmSpinner.length];
        for (int i = 0; i <
                this.urmSpinner.length; i++) {
            urmValues[i] = Double.parseDouble(urmSpinner[i].getValue().toString());
        }

        return urmValues;
    }

    private void calculate() throws CalculationException {
        double[] urmValues = getChartUrmValues();
        provider.calculatePdmTransitions(urmValues);

        if (chart != null) {
            this.updateChartData(urmValues);
            this.updateChartData(provider.getPdmOptimizations(this.getSelectedDmus(), 0));
        } else {
            this.drawChart(urmValues, provider.getPdmOptimizations(this.getSelectedDmus(), 0));
        }

        this.setScrollandProgressBar();
        setDmuListColors();

    }

    private void setDmuListColors() {
        for (int i = 0; i <
                this.jPanel2.getComponentCount(); i++) {
            DmuPanel temp = (DmuPanel) jPanel2.getComponent(i);
            if (!temp.isHeader) {
                if (temp.isChecked()) {
                    temp.setColor(this.getColor(i-1));
                } else {
                    temp.setColor(Color.getColor("ColorUIResource"));
                }


            }
        }
    }

    private List<Integer> getSelectedDmus() {
        List<Integer> dmus = new ArrayList<Integer>();
        //no header, start with 1
        for (int i = 1; i < jPanel2.getComponentCount(); i++) {
            DmuPanel x = (DmuPanel) jPanel2.getComponent(i);
            if (x.isChecked()) {
                dmus.add(i - 1);
            }

        }
        return dmus;
    }

    private void setScrollandProgressBar() {
        //this.jScrollBar1.setValues(provider.getTransitionList().size()-1, 0, 0, provider.getTransitionList().size()-1);
        this.jScrollBar1.setVisibleAmount(1);
        this.jScrollBar1.setMaximum(provider.getTransitionList().size());
        this.jScrollBar1.setMinimum(0);
        this.jScrollBar1.setValue(provider.getTransitionList().size());
        //this.jScrollBar1.setVisibleAmount(2);
        this.jScrollBar1.addAdjustmentListener(this);
        this.jScrollBar1.repaint();

        this.jProgressBar1.setStringPainted(true);
        this.jProgressBar1.setMinimum(0);
        this.jProgressBar1.setMaximum(provider.getTransitionList().size()-1);

        this.scrollBarChanged(this.jScrollBar1.getValue(), true);
    }
    private int getReverseValue(int newScrollbarValue){
        return provider.getTransitionList().size() - (newScrollbarValue+1);
    }
    private void scrollBarChanged(int newVal, boolean initial) {
        int reverseVal = getReverseValue(newVal);
        /*Util.print("transitionlist.size: " + provider.getTransitionList().size());
        Util.print("newVal " + newVal);
        Util.print("reverseVal " + reverseVal);*/
        List<PdmOptimization> ls = provider.getPdmOptimizations(this.getSelectedDmus(), reverseVal);
        if (!initial) {

            try {
                //actualize chart, dmuList and progress bar

                this.updateChartData(ls);
            } catch (CalculationException ex) {
                Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        int progressSize = newVal;
        this.jProgressBar1.setValue(progressSize);
        this.jProgressBar1.setString("Flexibility " + Util.getPercent(progressSize, this.jProgressBar1.getMaximum()) + "%");

        for (int i = 1; i <
                this.jPanel2.getComponentCount(); i++) {
            try {
                DmuPanel temp = (DmuPanel) this.jPanel2.getComponent(i);
                PdmOptimization p = provider.getTransitionList().get(reverseVal).get(i - 1);
                temp.setVariables(p.getOptimizationObjective(), p.getProfileDistance());
            } catch (CalculationException ex) {
                Logger.getLogger(ChartForm.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

    private void updateChartData(double[] urmValues) {
        Dataset dataset = this.chart.getDataset(0);

        //set urmValues
        for (int i = 0; i <
                urmValues.length; i++) {
            dataset.set(0, i, 0, Float.parseFloat(
                    String.valueOf(urmValues[i])));
        }

        this.chart.repaint();
    }

    private void updateChartData(List<PdmOptimization> pdmOpts) throws CalculationException {

        //DATASET
        Dataset dataset = this.chart.getDataset(0);
        dataset.setSize(pdmOpts.size() + 1, pdmOpts.get(0).getDmuList().outputSize, 1);
        //set pdmValues
        for (int x = 0; x < pdmOpts.size(); x++) {
            double[] relOutputWeight = Tool.getRelWeights(pdmOpts.get(x).getOptimizationOutputWeights());
            for (int i = 0; i < relOutputWeight.length; i++) {
                dataset.set(x + 1, i, 0, Float.parseFloat(
                        String.valueOf(Util.roundHalfUp(relOutputWeight[i], 0))));
            }

        }
        
        //LEGEND
        LegendProperties legendProps = this.chart.getLegendProperties();
        String[] legendLabels = new String[pdmOpts.size() + 1];
        legendLabels[0] = "Desired profile";
        for (int i = 0; i < pdmOpts.size(); i++) {
            legendLabels[i + 1] = Tool.erpVendors.get(pdmOpts.get(i).getObjectiveDmu());
        }

        legendProps.setLegendLabelsTexts(legendLabels);
        legendProps.setLegendExistence(false);

        //SCALE
        GraphChart2DProperties graphChart2DProps = this.chart.getGraphChart2DProperties();
        graphChart2DProps.setChartDatasetCustomGreatestValue(this.getCustomGreatestValue(pdmOpts));

        //COLORS
        MultiColorsProperties multiColorsProps = chart.getMultiColorsProperties(0);
        multiColorsProps.setColorsCustom(this.getColors(pdmOpts));
        multiColorsProps.setColorsCustomize(true);

        this.chart.repaint();
    }
    private Color getColor(int index){
        switch(index){
            case -1:
                return Color.GRAY;
            case 0:
                return Color.getHSBColor(114, 40, 94);
            case 1:
                return Color.getHSBColor(209, 83, 89);
            case 2:
                return new Color(10,175,118);
        }
        return Color.RED;
    }

    private Color[] getColors(List<PdmOptimization> pdmOpts){
        Color[] colors = new Color[pdmOpts.size() +1];
        //URM color
        colors[0] = getColor(-1);
        for(int i=0;i<pdmOpts.size();i++){
            colors[i+1] = this.getColor(pdmOpts.get(i).getObjectiveDmu());
        }
        return colors;
    }
    private void drawChart(double[] urmValues, List<PdmOptimization> pdmOpts) throws CalculationException {
        // Configure object properties
        Object2DProperties object2DProps = new Object2DProperties();
        object2DProps.setObjectTitleExistence(false);

        // Configure chart properties
        Chart2DProperties chart2DProps = new Chart2DProperties();
        chart2DProps.setChartDataLabelsPrecision(-1);

        // Configure legend properties
        LegendProperties legendProps = new LegendProperties();
        String[] legendLabels = new String[pdmOpts.size() + 1];
        legendLabels[0] = "Desired profile";
        for (int i = 0; i < pdmOpts.size(); i++) {
            legendLabels[i + 1] = Tool.erpVendors.get(pdmOpts.get(i).getObjectiveDmu());
        }

        legendProps.setLegendLabelsTexts(legendLabels);
        legendProps.setLegendExistence(false);

        // Configure graph chart properties
        GraphChart2DProperties graphChart2DProps = new GraphChart2DProperties();

        

        graphChart2DProps.setLabelsAxisLabelsTexts(categories);
        graphChart2DProps.setNumbersAxisLabelsFontPointModel(17);
        graphChart2DProps.setLabelsAxisLabelsFontPointModel(17);
        graphChart2DProps.setChartDatasetCustomGreatestValue(this.getCustomGreatestValue(pdmOpts));
        graphChart2DProps.setChartDatasetCustomizeGreatestValue(true);
        //weightLabel
        // Configure graph properties
        GraphProperties graphProps = new GraphProperties();
        //graphProps.setGraphBarsExistence(false);
        //graphProps.setGraphAllowComponentAlignment (true);
        graphProps.setGraphBarsRoundingRatio(0f);
        graphProps.setGraphLabelsLinesExistence(true);
        graphProps.setGraphBetweenComponentsGapThicknessModel(20);
        //graphProps.setGraphBarsThicknessModel(1);
        //graphProps.setGraphOutlineComponentsExistence(true);

        Dataset dataset = new Dataset(pdmOpts.size() + 1, urmValues.length, 1);

        //set urmValues
        for (int i = 0; i <
                urmValues.length; i++) {
            dataset.set(0, i, 0, Float.parseFloat(
                    String.valueOf(urmValues[i])));
        }
//set pdmValues

        for (int x = 0; x <
                pdmOpts.size(); x++) {
            double[] relOutputWeight = Tool.getRelWeights(pdmOpts.get(x).getOptimizationOutputWeights());
            for (int i = 0; i <
                    relOutputWeight.length; i++) {
                dataset.set(x + 1, i, 0, Float.parseFloat(
                        String.valueOf(Util.roundHalfUp(relOutputWeight[i], 0))));
            }

        }

        // Configure graph component colors
        MultiColorsProperties multiColorsProps = new MultiColorsProperties();
        Color[] colors = this.getColors(pdmOpts);
        multiColorsProps.setColorsCustom(this.getColors(pdmOpts));
        multiColorsProps.setColorsCustomize(true);

        // Configure chart
        if (chart == null) {
            chart = new LBChart2D();
            chart.setObject2DProperties(object2DProps);
            chart.setChart2DProperties(chart2DProps);
            chart.setLegendProperties(legendProps);
            chart.setGraphChart2DProperties(graphChart2DProps);
            chart.addGraphProperties(graphProps);
            chart.addDataset(dataset);
            chart.addMultiColorsProperties(multiColorsProps);
            jPanel3.add(this.chart);
        }
// Optional validation: Prints debug messages if invalid only.

        if (!chart.validate(false)) {
            chart.validate(true);
        }

        chart.setPreferredSize(new Dimension(800, 400));
        // <-- End Chart2D configuration -->
        chart.repaint();
    }

    public void actionPerformed(ActionEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void adjustmentValueChanged(AdjustmentEvent e) {
        this.scrollBarChanged(e.getValue(), false);
    }
}
